<script setup lang="ts">
import { watchDebounced } from '@vueuse/core'
import chroma from 'chroma-js'
import * as echarts from 'echarts'
import { NNumberAnimation } from 'naive-ui'
import { onMounted, watch, ref, onUnmounted } from 'vue'

import { ScrollContainer } from '@/components'
import { toRefsPreferencesStore } from '@/stores'
import twc from '@/utils/tailwindColor'

import type { ECharts } from 'echarts'

defineOptions({
  name: 'DashboardMonitor',
})

const { sidebarMenu, navigationMode, themeColor, isDark } = toRefsPreferencesStore()

const systemStatus = ref<SystemStatusItem[]>(generateSystemStatus())
const recentAlerts = ref(generateRecentAlerts())

const cpuChart = ref<HTMLDivElement | null>(null)
let cpuChartInstance: ECharts | null = null
let cpuChartResizeHandler: (() => void) | null = null

const memoryChart = ref<HTMLDivElement | null>(null)
let memoryChartInstance: ECharts | null = null
let memoryChartResizeHandler: (() => void) | null = null

const networkChart = ref<HTMLDivElement | null>(null)
let networkChartInstance: ECharts | null = null
let networkChartResizeHandler: (() => void) | null = null

const diskChart = ref<HTMLDivElement | null>(null)
let diskChartInstance: ECharts | null = null
let diskChartResizeHandler: (() => void) | null = null

const CHART_CONFIG = {
  TIME_RANGE: Array.from({ length: 12 }, (_, i) => `${i * 5}m`),
}

interface SystemStatusItem {
  title: string
  value: number
  unit: string
  iconClass: string
  iconBgClass: string
  color: string
  trend: number[]
}

function generateSystemStatus(): SystemStatusItem[] {
  return [
    {
      title: 'CPU使用率',
      value: parseFloat((20 + Math.random() * 40).toFixed(1)),
      unit: '%',
      iconClass: 'iconify ph--cpu-bold text-blue-50 dark:text-blue-150',
      iconBgClass:
        'text-blue-500/5 bg-blue-400 ring-4 ring-blue-200 dark:bg-blue-650 dark:ring-blue-500/30 transition-all',
      color: twc.blue[500],
      trend: generateRandomTrend(60, 80),
    },
    {
      title: '内存使用率',
      value: parseFloat((40 + Math.random() * 30).toFixed(1)),
      unit: '%',
      iconClass: 'iconify ph--memory-stick-bold text-purple-50 dark:text-purple-150',
      iconBgClass:
        'text-purple-500/5 bg-purple-400 ring-4 ring-purple-200 dark:bg-purple-650 dark:ring-purple-500/30 transition-all',
      color: twc.purple[500],
      trend: generateRandomTrend(40, 70),
    },
    {
      title: '磁盘使用率',
      value: parseFloat((60 + Math.random() * 25).toFixed(1)),
      unit: '%',
      iconClass: 'iconify ph--hard-drive-bold text-green-50 dark:text-green-150',
      iconBgClass:
        'text-green-500/5 bg-green-400 ring-4 ring-green-200 dark:bg-green-650 dark:ring-green-500/30 transition-all',
      color: twc.green[500],
      trend: generateRandomTrend(60, 85),
    },
    {
      title: '网络流量',
      value: parseFloat((150 + Math.random() * 200).toFixed(0)),
      unit: 'MB/s',
      iconClass: 'iconify ph--wifi-bold text-orange-50 dark:text-orange-150',
      iconBgClass:
        'text-orange-500/5 bg-orange-400 ring-4 ring-orange-200 dark:bg-orange-650 dark:ring-orange-500/30 transition-all',
      color: twc.orange[500],
      trend: generateRandomTrend(150, 350),
    },
  ] as const
}

function generateRecentAlerts() {
  const alertTypes = ['info', 'warning', 'error', 'success']
  const alertMessages = [
    'CPU使用率超过阈值',
    '内存使用量过高',
    '磁盘空间不足',
    '网络连接中断',
    '服务重启成功',
    '数据库连接失败',
    '备份任务完成',
    '系统更新可用',
  ]

  return Array.from({ length: 6 }, (_, i) => ({
    id: i + 1,
    type: alertTypes[Math.floor(Math.random() * alertTypes.length)] as
      | 'info'
      | 'warning'
      | 'error'
      | 'success',
    message: alertMessages[Math.floor(Math.random() * alertMessages.length)],
    time: `${Math.floor(Math.random() * 24)}:${String(Math.floor(Math.random() * 60)).padStart(2, '0')}`,
    isRead: Math.random() > 0.3,
  }))
}

function generateRandomTrend(min: number, max: number) {
  return Array.from({ length: 12 }, () => Math.round(min + Math.random() * (max - min)))
}

const createTooltipConfig = (formatter?: any) => ({
  trigger: 'axis',
  backgroundColor: isDark.value ? twc.neutral[750] : '#fff',
  borderWidth: 1,
  borderColor: isDark.value ? twc.neutral[700] : twc.neutral[150],
  padding: 8,
  extraCssText: 'box-shadow: none;',
  textStyle: {
    color: isDark.value ? twc.neutral[400] : twc.neutral[600],
    fontSize: 12,
  },
  axisPointer: {
    type: 'none',
  },
  ...(formatter && { formatter }),
})

function initCpuChart() {
  if (!cpuChart.value) return

  const chart = echarts.init(cpuChart.value)
  const cpuStatus = systemStatus.value[0] as SystemStatusItem
  const cpuData = cpuStatus.trend

  const option = {
    title: {
      text: 'CPU使用率趋势',
      left: 0,
      top: 0,
      textStyle: {
        fontSize: 15,
        color: isDark.value ? twc.neutral[400] : twc.neutral[600],
        fontWeight: 'normal',
      },
    },
    tooltip: createTooltipConfig((params: any) => {
      const time = params[0].axisValue
      const value = params[0].value
      return `<div>${time}</div><div style="display: flex; align-items: center; margin-top: 4px;"><span style="display:inline-block; margin-right:4px; width:10px; height:10px; border-radius:50%; background-color:${cpuStatus.color};" ></span><span>CPU使用率: ${value}%</span></div>`
    }),
    grid: {
      left: 20,
      right: 20,
      top: 40,
      bottom: 20,
      containLabel: true,
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: CHART_CONFIG.TIME_RANGE,
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: isDark.value ? twc.neutral[400] : twc.neutral[600],
        fontSize: 12,
      },
      splitLine: { show: false },
    },
    yAxis: {
      type: 'value',
      min: 0,
      max: 100,
      interval: 20,
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: isDark.value ? twc.neutral[400] : twc.neutral[600],
        fontSize: 12,
        formatter: '{value}%',
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: isDark.value ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.08)',
          width: 1,
        },
      },
    },
    series: [
      {
        name: 'CPU使用率',
        type: 'line',
        data: cpuData,
        symbol: 'circle',
        showSymbol: false,
        smooth: true,
        lineStyle: {
          color: cpuStatus.color,
          width: 2,
        },
        areaStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              { offset: 0, color: chroma(cpuStatus.color).alpha(0.12).hex() },
              { offset: 1, color: chroma(cpuStatus.color).alpha(0.02).hex() },
            ],
          },
        },
      },
    ],
    animationDuration: 1000,
    animationEasing: 'cubicOut' as const,
  }

  chart.setOption(option)

  cpuChartInstance = chart
  cpuChartResizeHandler = () => chart.resize()
  window.addEventListener('resize', cpuChartResizeHandler, { passive: true })
}

function initMemoryChart() {
  if (!memoryChart.value) return

  const chart = echarts.init(memoryChart.value)
  const memoryStatus = systemStatus.value[1] as SystemStatusItem
  const memoryData = memoryStatus.trend

  const option = {
    title: {
      text: '内存使用率趋势',
      left: 0,
      top: 0,
      textStyle: {
        fontSize: 15,
        color: isDark.value ? twc.neutral[400] : twc.neutral[600],
        fontWeight: 'normal',
      },
    },
    tooltip: createTooltipConfig((params: any) => {
      const time = params[0].axisValue
      const value = params[0].value
      return `<div>${time}</div><div style="display: flex; align-items: center; margin-top: 4px;"><span style="display:inline-block; margin-right:4px; width:10px; height:10px; border-radius:50%; background-color:${memoryStatus.color};" ></span><span>内存使用率: ${value}%</span></div>`
    }),
    grid: {
      left: 20,
      right: 20,
      top: 40,
      bottom: 20,
      containLabel: true,
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: CHART_CONFIG.TIME_RANGE,
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: isDark.value ? twc.neutral[400] : twc.neutral[600],
        fontSize: 12,
      },
      splitLine: { show: false },
    },
    yAxis: {
      type: 'value',
      min: 0,
      max: 100,
      interval: 20,
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: isDark.value ? twc.neutral[400] : twc.neutral[600],
        fontSize: 12,
        formatter: '{value}%',
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: isDark.value ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.08)',
          width: 1,
        },
      },
    },
    series: [
      {
        name: '内存使用率',
        type: 'line',
        data: memoryData,
        symbol: 'circle',
        showSymbol: false,
        smooth: true,
        lineStyle: {
          color: memoryStatus.color,
          width: 2,
        },
        areaStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              { offset: 0, color: chroma(memoryStatus.color).alpha(0.12).hex() },
              { offset: 1, color: chroma(memoryStatus.color).alpha(0.02).hex() },
            ],
          },
        },
      },
    ],
    animationDuration: 1000,
    animationEasing: 'cubicOut' as const,
  }

  chart.setOption(option)

  memoryChartInstance = chart
  memoryChartResizeHandler = () => chart.resize()
  window.addEventListener('resize', memoryChartResizeHandler, { passive: true })
}

function initNetworkChart() {
  if (!networkChart.value) return

  const chart = echarts.init(networkChart.value)
  const networkStatus = systemStatus.value[3] as SystemStatusItem
  const networkData = networkStatus.trend

  const option = {
    title: {
      text: '网络流量趋势',
      left: 0,
      top: 0,
      textStyle: {
        fontSize: 15,
        color: isDark.value ? twc.neutral[400] : twc.neutral[600],
        fontWeight: 'normal',
      },
    },
    tooltip: createTooltipConfig((params: any) => {
      const time = params[0].axisValue
      const value = params[0].value
      return `<div>${time}</div><div style="display: flex; align-items: center; margin-top: 4px;"><span style="display:inline-block; margin-right:4px; width:10px; height:10px; border-radius:50%; background-color:${networkStatus.color};" ></span><span>网络流量: ${value} MB/s</span></div>`
    }),
    grid: {
      left: 20,
      right: 20,
      top: 40,
      bottom: 20,
      containLabel: true,
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: CHART_CONFIG.TIME_RANGE,
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: isDark.value ? twc.neutral[400] : twc.neutral[600],
        fontSize: 12,
      },
      splitLine: { show: false },
    },
    yAxis: {
      type: 'value',
      min: 0,
      max: 400,
      interval: 100,
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: isDark.value ? twc.neutral[400] : twc.neutral[600],
        fontSize: 12,
        formatter: '{value} MB/s',
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: isDark.value ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.08)',
          width: 1,
        },
      },
    },
    series: [
      {
        name: '网络流量',
        type: 'bar',
        data: networkData,
        barWidth: '60%',
        itemStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              { offset: 0, color: chroma(networkStatus.color).alpha(0.8).hex() },
              { offset: 1, color: chroma(networkStatus.color).alpha(0.3).hex() },
            ],
          },
          borderRadius: [3, 3, 0, 0],
        },
        emphasis: {
          itemStyle: {
            color: chroma(networkStatus.color).alpha(0.9).hex(),
          },
        },
      },
    ],
    animationDuration: 1000,
    animationEasing: 'cubicOut' as const,
  }

  chart.setOption(option)

  networkChartInstance = chart
  networkChartResizeHandler = () => chart.resize()
  window.addEventListener('resize', networkChartResizeHandler, { passive: true })
}

function initDiskChart() {
  if (!diskChart.value) return

  const chart = echarts.init(diskChart.value)
  const diskStatus = systemStatus.value[2] as SystemStatusItem
  const diskData = [
    {
      name: '已使用',
      value: diskStatus.value,
      itemStyle: { color: diskStatus.color },
    },
    {
      name: '可用',
      value: 100 - diskStatus.value,
      itemStyle: { color: isDark.value ? twc.neutral[700] : twc.neutral[200] },
    },
  ]

  const option = {
    title: {
      text: '磁盘使用情况',
      left: 0,
      top: 0,
      textStyle: {
        fontSize: 15,
        color: isDark.value ? twc.neutral[400] : twc.neutral[600],
        fontWeight: 'normal',
      },
    },
    tooltip: createTooltipConfig((params: any) => {
      return `<div>${params[0].name}: ${params[0].value}%</div>`
    }),
    grid: {
      left: 0,
      right: 0,
      top: 40,
      bottom: 0,
      containLabel: true,
    },
    series: [
      {
        name: '磁盘使用率',
        type: 'pie',
        radius: ['50%', '70%'],
        center: ['50%', '55%'],
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 8,
          borderColor: isDark.value ? twc.neutral[800] : '#fff',
          borderWidth: 2,
        },
        label: {
          show: false,
          position: 'center',
        },
        emphasis: {
          label: {
            show: true,
            fontSize: '24',
            fontWeight: 'bold',
            formatter: '{b}: {c}%',
            color: isDark.value ? twc.neutral[400] : twc.neutral[600],
          },
        },
        labelLine: {
          show: false,
        },
        data: diskData,
      },
    ],
    animationDuration: 1000,
    animationEasing: 'cubicOut' as const,
  }

  chart.setOption(option)

  diskChartInstance = chart
  diskChartResizeHandler = () => chart.resize()
  window.addEventListener('resize', diskChartResizeHandler, { passive: true })
}

function resizeAllCharts() {
  if (cpuChartInstance) cpuChartInstance.resize()
  if (memoryChartInstance) memoryChartInstance.resize()
  if (networkChartInstance) networkChartInstance.resize()
  if (diskChartInstance) diskChartInstance.resize()
}

watchDebounced([() => sidebarMenu.value, () => navigationMode.value], resizeAllCharts, {
  debounce: 300,
  deep: true,
})

watch([isDark, themeColor], () => {
  // 销毁并重新初始化图表以适应主题变化
  if (cpuChartInstance) {
    if (cpuChartResizeHandler) {
      window.removeEventListener('resize', cpuChartResizeHandler)
      cpuChartResizeHandler = null
    }
    cpuChartInstance.dispose()
    cpuChartInstance = null
  }

  if (memoryChartInstance) {
    if (memoryChartResizeHandler) {
      window.removeEventListener('resize', memoryChartResizeHandler)
      memoryChartResizeHandler = null
    }
    memoryChartInstance.dispose()
    memoryChartInstance = null
  }

  if (networkChartInstance) {
    if (networkChartResizeHandler) {
      window.removeEventListener('resize', networkChartResizeHandler)
      networkChartResizeHandler = null
    }
    networkChartInstance.dispose()
    networkChartInstance = null
  }

  if (diskChartInstance) {
    if (diskChartResizeHandler) {
      window.removeEventListener('resize', diskChartResizeHandler)
      diskChartResizeHandler = null
    }
    diskChartInstance.dispose()
    diskChartInstance = null
  }

  initCpuChart()
  initMemoryChart()
  initNetworkChart()
  initDiskChart()
})

onMounted(() => {
  initCpuChart()
  initMemoryChart()
  initNetworkChart()
  initDiskChart()
})

onUnmounted(() => {
  if (cpuChartInstance) {
    if (cpuChartResizeHandler) {
      window.removeEventListener('resize', cpuChartResizeHandler)
      cpuChartResizeHandler = null
    }
    cpuChartInstance.dispose()
    cpuChartInstance = null
  }

  if (memoryChartInstance) {
    if (memoryChartResizeHandler) {
      window.removeEventListener('resize', memoryChartResizeHandler)
      memoryChartResizeHandler = null
    }
    memoryChartInstance.dispose()
    memoryChartInstance = null
  }

  if (networkChartInstance) {
    if (networkChartResizeHandler) {
      window.removeEventListener('resize', networkChartResizeHandler)
      networkChartResizeHandler = null
    }
    networkChartInstance.dispose()
    networkChartInstance = null
  }

  if (diskChartInstance) {
    if (diskChartResizeHandler) {
      window.removeEventListener('resize', diskChartResizeHandler)
      diskChartResizeHandler = null
    }
    diskChartInstance.dispose()
    diskChartInstance = null
  }
})
</script>

<template>
  <ScrollContainer wrapper-class="flex flex-col gap-y-4 max-sm:gap-y-2">
    <div class="grid grid-cols-1 gap-4 max-sm:gap-2 md:grid-cols-2 lg:grid-cols-4">
      <div
        v-for="(status, index) in systemStatus"
        :key="index"
        class="flex items-center justify-between gap-x-4 overflow-hidden rounded border border-naive-border bg-naive-card p-6 transition-[background-color,border-color]"
      >
        <div class="flex-1">
          <span class="text-sm font-medium text-neutral-450">{{ status.title }}</span>
          <div class="mt-1 mb-1.5 flex gap-x-4 text-2xl text-neutral-700 dark:text-neutral-400">
            <NNumberAnimation
              :to="status.value"
              :precision="1"
            />
            <span>{{ status.unit }}</span>
          </div>
          <div class="text-xs text-neutral-500 dark:text-neutral-400">实时监控中...</div>
        </div>
        <div>
          <div
            class="grid place-items-center rounded-full p-3"
            :class="status.iconBgClass"
          >
            <span
              class="size-7"
              :class="status.iconClass"
            />
          </div>
        </div>
      </div>
    </div>

    <div class="grid grid-cols-1 gap-4 overflow-hidden max-sm:gap-2 lg:grid-cols-12">
      <div class="col-span-1 lg:col-span-6">
        <div class="grid grid-cols-1 gap-4 max-sm:gap-2">
          <div
            class="rounded border border-naive-border bg-naive-card px-5 pt-5 pb-4.5 transition-[background-color,border-color]"
            style="height: 200px"
          >
            <div
              ref="cpuChart"
              class="h-full"
            />
          </div>
          <div
            class="rounded border border-naive-border bg-naive-card px-5 pt-5 pb-4.5 transition-[background-color,border-color]"
            style="height: 200px"
          >
            <div
              ref="memoryChart"
              class="h-full"
            />
          </div>
        </div>
      </div>
      <div class="col-span-1 lg:col-span-6">
        <div class="grid grid-cols-1 gap-4 max-sm:gap-2">
          <div
            class="rounded border border-naive-border bg-naive-card px-5 pt-5 pb-4.5 transition-[background-color,border-color]"
            style="height: 200px"
          >
            <div
              ref="networkChart"
              class="h-full"
            />
          </div>
          <div
            class="rounded border border-naive-border bg-naive-card px-5 pt-5 pb-4.5 transition-[background-color,border-color]"
            style="height: 200px"
          >
            <div
              ref="diskChart"
              class="h-full"
            />
          </div>
        </div>
      </div>
    </div>

    <div class="grid grid-cols-1 gap-4 overflow-hidden max-sm:gap-2">
      <div class="col-span-1">
        <div
          class="rounded border border-naive-border bg-naive-card p-6 transition-[background-color,border-color]"
        >
          <div class="mb-4 flex items-center justify-between">
            <h3 class="text-lg font-medium text-neutral-700 dark:text-neutral-400">最近告警</h3>
            <span class="text-sm text-neutral-450">共 {{ recentAlerts.length }} 条</span>
          </div>
          <div class="overflow-x-auto">
            <table class="w-full text-left">
              <thead class="border-b border-naive-border">
                <tr>
                  <th class="px-4 py-3 text-sm font-medium text-neutral-450">类型</th>
                  <th class="px-4 py-3 text-sm font-medium text-neutral-450">消息</th>
                  <th class="px-4 py-3 text-sm font-medium text-neutral-450">时间</th>
                  <th class="px-4 py-3 text-sm font-medium text-neutral-450">状态</th>
                </tr>
              </thead>
              <tbody>
                <tr
                  v-for="alert in recentAlerts"
                  :key="alert.id"
                  class="border-b border-naive-border transition-colors hover:bg-neutral-50 dark:hover:bg-neutral-750"
                >
                  <td class="px-4 py-3">
                    <span
                      class="inline-flex items-center justify-center rounded-full p-1"
                      :class="{
                        'bg-blue-100 text-blue-600 dark:bg-blue-500/20 dark:text-blue-400':
                          alert.type === 'info',
                        'bg-yellow-100 text-yellow-600 dark:bg-yellow-500/20 dark:text-yellow-400':
                          alert.type === 'warning',
                        'bg-red-100 text-red-600 dark:bg-red-500/20 dark:text-red-400':
                          alert.type === 'error',
                        'bg-green-100 text-green-600 dark:bg-green-500/20 dark:text-green-400':
                          alert.type === 'success',
                      }"
                    >
                      <span
                        class="size-4"
                        :class="{
                          'iconify ph--info': alert.type === 'info',
                          'iconify ph--warning': alert.type === 'warning',
                          'iconify ph--x-circle': alert.type === 'error',
                          'iconify ph--check-circle': alert.type === 'success',
                        }"
                      />
                    </span>
                  </td>
                  <td class="px-4 py-3 text-sm text-neutral-600 dark:text-neutral-400">
                    {{ alert.message }}
                  </td>
                  <td class="px-4 py-3 text-sm text-neutral-500 dark:text-neutral-500">
                    {{ alert.time }}
                  </td>
                  <td class="px-4 py-3">
                    <span
                      class="inline-flex items-center rounded-full px-2 py-1 text-xs font-medium"
                      :class="{
                        'bg-neutral-100 text-neutral-600 dark:bg-neutral-700 dark:text-neutral-400':
                          alert.isRead,
                        'bg-blue-100 text-blue-600 dark:bg-blue-500/20 dark:text-blue-400':
                          !alert.isRead,
                      }"
                    >
                      {{ alert.isRead ? '已读' : '未读' }}
                    </span>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  </ScrollContainer>
</template>
